import 'dart:math';

void main(List<String> arguments) {
  var message = StringBuffer('Dart is fun');
  for (var i = 0; i < 5; i++) {
    message.write('!');
  }
  var callbacks = [];
  for (var i = 0; i < 2; i++) {
    callbacks.add(() => print(i));
  }
  for (final c in callbacks) {
    c();
  }

  var collection = [1, 2, 3];
  collection.forEach(print);

  outerLoop:
  for (var i = 1; i <= 3; i++) {
    for (var j = 1; j <= 3; j++) {
      print('i = $i, j = $j');
      if (i == 2 && j == 2) {
        break outerLoop;
      }
    }
  }
  print('outerLoop exited');

  outerLoop:
  for (var i = 1; i <= 3; i++) {
    for (var j = 1; j <= 3; j++) {
      if (i == 2 && j == 2) {
        continue outerLoop;
      }
      print('i = $i, j = $j');
    }
  }

  var i = 1;
  outerLoop:
  while (i <= 3) {
    var j = 1;
    while (j <= 3) {
      print('i = $i, j = $j');
      if (i == 2 && j == 2) {
        break outerLoop;
      }
      j++;
    }
    i++;
  }
  print('outerLoop exited');

  i = 1;
  outerLoop:
  while (i <= 3) {
    var j = 1;
    while (j <= 3) {
      if (i == 2 && j == 2) {
        i++;
        continue outerLoop;
      }
      print('i = $i, j = $j');
      j++;
    }
    i++;
  }

  i = 1;
  outerLoop:
  do {
    var j = 1;
    do {
      print('i = $i, j = $j');
      if (i == 2 && j == 2) {
        break outerLoop;
      }
      j++;
    } while (j <= 3);
    i++;
  } while (i <= 3);
  print('outerLoop exited');

  i = 1;
  outerLoop:
  do {
    var j = 1;
    do {
      if (i == 2 && j == 2) {
        i++;
        continue outerLoop;
      }
      print('i = $i, j = $j');
      j++;
    } while (j <= 3);
    i++;
  } while (i <= 3);

  var command = 'OPEN';
  switch (command) {
    case 'CLOSED':
      print('Closed.');
    case 'PENDING':
      print('Pending.');
    case 'APPROVED':
      print('Approved.');
    case 'DENIED':
      print('Denied.');
    case 'OPEN':
      print('Open');
    default:
      print('Unknown');
  }

  switch (command) {
    case 'OPEN':
      print('Open.');
      continue newCase;

    case 'DENIED':
    case 'CLOSED':
      print('Closed.');

    newCase:
    case 'PENDING':
      print('Now closed.');
  }

  var charCode = 'slash';
  switch (charCode) {
    case 'slash' || 'star' || 'plus' || 'minus':
      print('Operator');
    case 'comma' || 'semicolon':
      print('Punctation.');
    case 'number':
      print('Number.');
    default:
      throw FormatException('Invalid');
  }

  var token = switch (charCode) {
    'slash' || 'star' || 'plus' || 'minus' => 'operator',
    'comma' || 'semicolon' => 'punctation',
    'number' => 'number',
    _ => throw FormatException('Invalid'),
  };

  bool nullableBool = true;
  switch (nullableBool) {
    case true:
      print('yes');
    case false:
      print('no');
  }

  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }

  try {
    breedMoreLlamas();
  } catch (e) {
    print('Error: $e');
  } finally {
    cleanLlamaStalls();
  }

  var text = 'a.txt';
  assert(text != null);
  var number = 10;
  assert(number < 100);
  var urlString = 'https: www.123456.com';
  assert(urlString.startsWith('https'));
  assert(
    urlString.startsWith('https'),
    'URL($urlString) should start with "https".',
  );
}

sealed class Shape {}

class Square implements Shape {
  final double length;
  Square(this.length);
}

class Circle implements Shape {
  final double radius;
  Circle(this.radius);
}

double calculateArea(Shape shape) => switch (shape) {
  Square(length: var l) => l * l,
  Circle(radius: var r) => pi * r * r,
};

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++);
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow;
  }
}

void breedMoreLlamas() {}
void cleanLlamaStalls() {}
